ソフトウェア・テストの技法 第 2 版
https://m.media-amazon.com/images/I/41IeGuTGutL.jpg
2020-05-09 購入
2020-07-04 読了
nobuoka.icon 感想・まとめ
テストの心構え (意図通り動くことを確認するためではなく、エラーを見つけるつもりでやれ) から始まり、テスト以外の検査手法 (コードインスペクションやウォークスルーなど) やデバッグについてなどの説明もあり、テストに関連する様々な話題を学ぶことができる
肝心のテストについては、テストケース作成で使える思考法 (同値分割) や、モジュールテストと上級テストといったテストの種類の説明、エクストリームテスト (アジャイル手法におけるテスト) といった内容が書かれている
個別の内容としては知っていることも多かったけど、知っていることについても自分の中であんまり整理できてなかったので整理できて良かった
本書におけるシステムテストは、「システムまたはプログラムが、元の目的仕様書の内容に合わないことを示そうとする過程」 という説明になっているのだけど、そもそも 「目的仕様書ってなんなんだっけ?」 という気持ちになった 一部同意できない内容が書かれていたり、内容的に古く感じる部分もわりとあるっちゃあるが、ソフトウェアテストについて一通り基本的なところを学ぶのにはちょうどよい書籍だと思う
例えば、テスト完了条件として 「テストで発見されるべきエラーの個数を推定し、その個数のエラーを発見できたら完了とする」 のが良い、というようなことが書かれていて、あんまり同意できない (詳細は下記の内容メモに書いた)
内容メモ
1 章 : 自己診断テスト
下記のようなプログラムをテストするために必要なテスト入力値はどのようなものか? (テストケースの洗い出し)
このプログラムは、入力ダイアログから 3 つの整数値を読む。 この 3 つの値は、それぞれ三角形の 3 辺の長さをあらわすものとする。 プログラムは、三角形が不等辺三角形、二等辺三角形、正三角形のうちのどれであるかを示すメッセージを表示する。
2 章 : プログラム・テストの心理学と経済学
テストは技術的な話ではあるが、心理的あるいは経済的な考慮も重要
テストの心理学
多くの開発者は、テストを 「プログラムが意図通り動くことを確認するためのもの」 というように考えている
それがテストの貧困さの要因の一つ
テストとは、エラーを見つけるつもりでプログラムを実行する過程である
プログラムはエラーを含んでいるという仮定のもとでテストを行っていくべき
言葉遊びのように思えるかもしれないが、人は目標に向かって進んでいく性質があるので、適切な目標設定が心理的に重要
「成功」 や 「失敗」 という言葉についても、エラーを見つけられたテストこそが成功である
テストの経済学
全てのエラーを発見するようなテストは現実的ではないし、しばしば不可能 → テストの経済学
テストする人がプログラムに対してもつ仮定と、テストケース設計方法をどうするか
戦略
ブラックボックステスト : 徹底的な入力テストが基準となる → 経済的でない
ホワイトボックステスト : 徹底的経路テストを目指したい → とはいえそれも完全ではない
ブラックボックステストとホワイトボックステストの要素をうまく組み合わせて、妥当なテスト法を確立するのが良さそう
ソフトウェアテストの原則
1. テストケースとして、予想される出力または結果を定義しておくことが必要不可欠
当たり前のようだが、これが見過ごされて本来エラーにすべき結果をいいように解釈してエラーにしないことがある
2. プログラマは自身のプログラムをテストしてはならない
自身の作品を破壊的に見ることは心理的に困難
また、プログラマの誤解によりエラーが発生する可能性もあり、その発見は本人には難しい
3. プログラム開発グループは、自分たちのプログラムをテストしてはならない
上の原則と似ている心理的な要素。 さらに、時間やコストといった面での組織的な圧力を避けるため
4. それぞれのテストの結果を完全に検査せよ
最も明白だろうが、エラーの兆候が見過ごされることも多い
5. テストケースは予想できる正しい入力条件ばかりでなく、予想しない誤った場合も考えて書く必要がある
6. 意図されたように動くかどうかをみただけでは半ば成功したに過ぎない。 残りの半分は意図されなかった動きをするかどうか調べること
7. プログラムが使い捨てでなければ、テストケースも使い捨てにしてはならない
8. エラーは見つからないだろうという仮定でテスト計画を立ててはならない
9. プログラムのある部分でエラーが残っている確率は、既にその部分で見つかったエラーの数に比例する
10. テストとは非常に創造的であり、知的に挑戦しがいがある仕事である
3 章 : プログラムの検査、ウォークスルー、検討
昔はソースコードは機械のためのもので人が読むものではないというような認識がなされていた
現代では、テストの一部としてコードを学ぶという概念が広く受け入れられている
人間によるテストの技法についても説明
検査とウォークスルー
プログラム作成者以外が読むことによる効果
エラーの症状しか見つけられないテストと違い、エラーの正しい位置までわかる
人的作業による検査は、コンピュータによるテストと補完関係にある (それぞれで発見しやすいエラーが異なる)
机上チェック : 個人による検査、あるいはウォークスルー
たいていの人にとってはあまり実りはない。 規律がないことと、自分が書いたコードをテストするのは効果がない、ということから
他の人が書いたコードの机上チェックの方がよいが、コード検査やウォークスルーには劣る
仲間内での会合の方が、健全な競争環境が作られるため。 人はエラーを発見することで目立ちたい
仲間内での評価 (peer rating)
これはエラーを発見することを目的にしてはいない (コードの読み合わせの考えに関係があるので紹介)
6 人以上で集まり、全員が自分のプログラムを 2 つ選ぶ (最高の出来だと思うものと、劣るもの)
匿名で他の参加者のプログラムを 4 つ与えられる。 2 つが最高の出来だと思うもので、2 つは劣るもの (どれがそうかはわからない)
参加者は渡された 4 つのプログラムについて、それぞれ 30 分ずつ時間を使って、7 段階で評価を行う
理解しやすさ、高レベルでの設計について、低レベルでの設計について、変更が容易か、自分が書いたとしたら誇りに思えるか、という軸で
4 章 : テスト・ケースの設計
(2 章の心理的な側面を除けば) 効果的なテストケースの設計や発見が一番重要
手法
ホワイトボックステスト
判定条件網羅 (decision coverage) (分岐網羅; branch coverage) : それぞれの判定条件が真と偽の結果を少なくとも一度ずつ持つようにテストケースを書く if (A & B) みたいな判定条件であれば、A & B が真と偽を取るようなテストケース
条件網羅 (condition coverage) : 判定におけるあらゆる条件で、全ての可能な結果を少なくとも 1 回は取るようにテストケースを書く if (A & B) みたいな判定条件でいうと、A という条件が真と偽をとり、B という条件も真と偽を取るようなテストケース
判定の中の条件についてのみ考えるので、判定条件自体が真と偽の結果を少なくとも一度ずつ持つとは限らない
「A が真で B が偽」 というパターンと 「A が偽で B が真」 というパターン
判定条件 / 条件網羅 : 1 つの判定条件でのそれぞれの個別条件が全ての可能な結果を少なくとも 1 回はとり、それぞれの判定条件が可能な結果を少なくとも 1 回は取る これでも足りない : if (A & B) であれば、「A も B も真」 と 「A も B も偽」 で判定条件 / 条件網羅だが、実際のプログラム的には A が真の時点で B が評価されない場合が多く、「B が真」 の条件が実際にはテストされていないことになる
ブラックボックステスト
これらを組み合わせた戦略
入力条件の組み合わせを含んでいたら、原因 - 結果グラフの作成から
どんな場合でも限界値分析
入力と出力の有効および無効の同値クラスを見分けて、必要ならテストケースに補足
さらにエラー推測技法も使う
上記を考慮に入れながら、プログラムの論理を調べる。 上記のテストケースに不足しているテストケースがあれば、それを加える
目的 : そのモジュールを定義している機能仕様あるいはインターフェイス仕様と比較すること
モジュールが仕様にあっていることではなく、モジュールが仕様に反していることを示すこと
実際に稼働するプログラムを作るためのモジュールの統合について
増加テスト : テストされたモジュールに統合してモジュールテストを行う 増加テストの 2 つの手法
6 章 : 上級テスト
https://gyazo.com/6945b3c949961c953eb48d4ffeb86b03
文書について
外部仕様書 : ユーザーに対してプログラムの正確な表現を示す その後の過程については、プログラムをどのようにして組み立てるかを示す
テスト計画と制御
テスト完了基準
いつ終わるのか?
予定していたテスト期間が過ぎたときとか、全てのテストケースでエラーが発見できなかったとき、という基準は無益
テスト期間はテストせずとも終わるし、テストケースでエラーが発見されないというのはテストケースの品質に関係ない (むしろエラーを発見しないテストケースを作るインセンティブが働く)
有益な 3 種の基準
1. テストケースが複数条件網羅基準を満たして、モジュール・インターフェイス仕様の限界値分析から得られており、テストケースが不成功に終わること これらの手法が使えるテストは制限されているので、全てのテストで使えるわけではないのと、テストケース作成者がこれらの手法を適切に使えているかどうかを判断するのが難しい
2. テストで発見されるべきエラーの個数を推定し、その個数のエラーを発見できたら完了とする
これ、目安としてはいいと思うんだけど、実際の完了基準に使えるかというとどうかなぁ、という気はする nobuoka.icon
一定期間経っても基準に達しない場合には、テストケースが悪いのかプログラムが良いのかを判断するために、外部の人間にテストケースの良さを判断してもらうよう依頼できる、と書かれている
それだったら最初からテストケースの良し悪しを判断すればよいのでは??? nobuoka.icon
3. テスト期間中の週ごとのエラー発見数をプロットして、傾向を見て判断 (減ってきたら OK、まだまだ発見されているなら続ける必要がある、という)
基本的に大規模なテストを考慮してるっぽくて、小さなエンハンスの時にどうするかみたいなのは考慮されてなさそう nobuoka.icon
7 章 : デバッグ
疑わしいエラーの正確な性質と場所を特定すること
エラーの修正をすること
力ずくでのデバッグは効果が薄い
思考型でデバッグすべき
帰納法によるデバッグ
https://gyazo.com/0a3e042dd8b32580aeea04149e603eb4
推定によるデバッグ
https://gyazo.com/2808faa56640c7d6f5da90103ed20d34
帰納法と推定の違いがあんまりわかんないな nobuoka.icon
どっちも仮説を立てて仮説を立てるって感じな気がするけど
推定の方はあり得る仮説をまず洗い出すって感じで、帰納法の方はまずはデータを集めて事実を特定する、って感じなのかな
テストによるデバッグ
エラーを発見するためのテストではなく、エラー個所を特定するためのテストを行ってエラー個所を絞り込む
エラーを分析してそこから学習することには大きな価値がある
どこでエラーが起きたのか?
誰がエラーを作ったのか? (特定の人が同様のエラーを起こしているなら教育で解決できるかもしれない)
何が誤って起きたのか、どうすれば防げたのか、どうしたらさらに早く発見できたのか、など
8 章 : エクストリーム・テスト
エクストリーム・プログラミング (XP) と伝統的な開発プロセスの違い コーディングの前にアプリケーションのすべての詳細を設計するようなことを避ける
不必要な機能をもつコードを避ける (必要かもしれないが必須ではない、というときには通常はそれをリリースしない)
本質的な違いは、テストに集中すること
伝統的なソフト開発モデルでは、設計段階の後、コーディングを行い、その後にテスト・インタフェイスを作成する
XP では最初にテストを作成しなければならない
エクストリーム・テストの概念
2 つのテスト形式 : 単体テストと受け入れテスト
コードに変更が起きた時には、あなたはいつでも単体テストを実行する
顧客は主なリリース時点で受け入れテストを実行する
エクストリーム単体テスト
2 つの原則
全てのコードモジュールは、コーディング開始前に単体テストを持たなければならない
全てのコードモジュールは、リリース前に単体テストに通らなければならない
受け入れテスト
目的 : アプリケーションが、機能性や有用性といった他の要求を満たすかどうかを判定すること
あなたは顧客と設計・計画段階で受け入れテストを作成する
顧客が受け入れテストを指揮する
9 章 : インターネット・アプリケーションのテスト
Web サービスは手軽に使えるから消費者市場での競争が激しくなっていて、消費者にとってパッケージ・アプリケーションよりも Web に期待する水準が上がっている (ように感じられる)
そういう状況なのでインターネットアプリケーションのテストは重要
環境が多様だったり構成要素が複雑だったりするので、テストは困難
プレゼンテーション層、ビジネスロジック層、データアクセス層はそれぞれ別にテスト可能